<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>组合模式</title>
</head>
<body>

调用组合对象 的execute方法，程序会递归调用组合对象 下面的叶对象的execute方法
<script>
// 文件 叶对象
function File(name) {
    this.name = name;
    this.parent = null;
}

File.prototype = {
    constructor: File,

    add: function() {
        console.log('文件里面不能添加文件');
    },

    scan: function() {
        var name = [this.name];
        var parent = this.parent;

        while (parent) {
            name.unshift(parent.name);
            parent = parent.parent;
        }

        console.log(name.join(' / '));
    }
};
var file1 = new File('HTML1.pdf');
var file2 = new File('HTML2.pdf');
var file3 = new File('HTML3.pdf');
var file4 = new File('HTML4.pdf');
var file5 = new File('HTML5.pdf');
var file6 = new File('HTML6.pdf');

// 文件夹 组合对象
function Folder(name) {
    this.name = name;
    this.parent = null;
    this.files = [];
}

Folder.prototype = {
    constructor: Folder,

    add: function(file) {
        file.parent = this;
        this.files.push(file);

        return this;
    },

    scan: function() {
        // 委托给叶对象处理
        for (var i = 0; i < this.files.length; ++i) {
            this.files[i].scan();
        }
    },

    remove: function(file) {
        if (typeof file === 'undefined') {
            this.files = [];
            return;
        }

        for (var i = 0; i < this.files.length; ++i) {
            if (this.files[i] === file) {
                this.files.splice(i, 1);
            }
        }
    }
};

var folder1 = new Folder('Web 1');
var folder2 = new Folder('Web 2');
folder1.add(file1).add(file2).add(file3);
folder1.scan();
folder2.add(file4).add(file5).add(file6);
folder2.scan();
</script>
</body>
</html>